﻿
#include <shlwapi.h>
#include "zyListBoxEx.h"


DarkMoonUI::zyListBoxEx::zyListBoxEx()
{
	SetMember(L"this", (LONG_PTR)this);
	m_obj->setWndProc(zyListBoxEx_WndProc);
	m_obj->setChildWndProc(zyListBoxEx_ChildWndProc);
	m_obj->setDestroy(zyListBoxEx_Destroy);
	
}
DarkMoonUI::zyListBoxEx::~zyListBoxEx()
{

}
void DarkMoonUI::zyListBoxEx::zyListBoxEx_DrawBackColor(Gdiplus::Graphics* graphics, DRAWITEMSTRUCT* dis) {
	if (dis->itemData) {
		zyListBoxItem* lbi = (zyListBoxItem*)dis->itemData;
		if ((dis->itemState & ODS_SELECTED) != 0)
			graphics->Clear(lbi->selBackColor);
		else
			graphics->Clear(lbi->backColor);
	}
}
int DarkMoonUI::zyListBoxEx::zyListBoxEx_DrawCheckBox(HWND hWnd, HDC bg, DRAWITEMSTRUCT* dis) {
	if (!dis->itemData) return 0;

	HTHEME htheme = OpenThemeData(hWnd, L"Button");
	int bmsize = 14;
	int states = 0;
	zyListBoxItem* lbi = (zyListBoxItem*)dis->itemData;
	RECT rc = { lbi->marginChecked, (dis->rcItem.bottom - dis->rcItem.top - bmsize) / 2, lbi->marginChecked + bmsize + lbi->marginChecked,
		(dis->rcItem.bottom - dis->rcItem.top - bmsize) / 2 + bmsize };
	if (htheme) {
		int part = BP_CHECKBOX;
		if ((lbi->state & zyLBS_CHECKED) != 0 && (lbi->state & zyLBS_DISABLE) != 0)
			states = CBS_CHECKEDDISABLED;
		else if ((lbi->state & zyLBS_CHECKED) != 0 && (lbi->state & zyLBS_DISABLE) == 0)
			states = CBS_CHECKEDNORMAL;
		else if ((lbi->state & zyLBS_CHECKED) == 0 && (lbi->state & zyLBS_DISABLE) !=0)
			states = CBS_UNCHECKEDDISABLED;
		else if ((lbi->state & zyLBS_CHECKED) == 0 && (lbi->state & zyLBS_DISABLE) ==0)
			states = CBS_UNCHECKEDNORMAL;
		DrawThemeBackground(htheme, bg, part, states, &rc, 0);
		CloseThemeData(htheme);
	}
	else {
		states = DFCS_BUTTONCHECK;
		if ((lbi->state & zyLBS_CHECKED) != 0 && (lbi->state & zyLBS_DISABLE) != 0)
			states |= DFCS_CHECKED | DFCS_INACTIVE;
		else if ((lbi->state & zyLBS_CHECKED) != 0 && (lbi->state & zyLBS_DISABLE) == 0)
			states |= DFCS_CHECKED;
		else if ((lbi->state & zyLBS_CHECKED) == 0 && (lbi->state & zyLBS_DISABLE) != 0)
			states |= DFCS_INACTIVE;
		else if ((lbi->state & zyLBS_CHECKED) == 0 && (lbi->state & zyLBS_DISABLE) ==0)
			states |= 0;
		DrawFrameControl(bg, &rc, DFC_BUTTON, states);
	}
	return rc.right;
}
void DarkMoonUI::zyListBoxEx::zyListBoxEx_DrawImageAndText(HWND hWnd, HDC hdc, Gdiplus::Graphics* graphics, DRAWITEMSTRUCT* dis, int left) {
	if (!dis->itemData) return;

	zyListBoxItem* lbi = (zyListBoxItem*)dis->itemData;
	if (!lbi) return;

	resObject* pImageList = (resObject*)GetMember(L"pImageList");
	if (pImageList && lbi->NoImageList == 0) {
		zyLmageList imgList;
        imgList.setObject(pImageList);
		POINT size = imgList.取图标尺寸();
		RECT rc = { left + lbi->marginImage, (dis->rcItem.bottom - dis->rcItem.top - size.y) / 2,
			left + lbi->marginImage + size.x, (dis->rcItem.bottom - dis->rcItem.top - size.y) / 2 + size.y };
		if (lbi->iImage) {
			if((dis->itemState & ODS_SELECTED) != 0)
                imgList.画图标Ex(lbi->iImage, hdc, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, (int)lbi->selBackColor.GetValue(), 0, 1);//图片组绘制_透明
			else
                imgList.画图标Ex(lbi->iImage, hdc, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, (int)lbi->backColor.GetValue(), 0, 0);//图片组绘制_正常
		}
		left = left + lbi->marginImage + size.x;
	}
	else if (lbi->Image  && lbi->NoImageList == 0) {
		if (lbi->Image) {
			Gdiplus::Rect rcf = { left + lbi->marginImage, (dis->rcItem.bottom - dis->rcItem.top - lbi->ImageHeight) / 2, lbi->ImageWidth, lbi->ImageHeight };
			graphics->DrawImage(lbi->Image, rcf, 0, 0, lbi->Image->GetWidth(), lbi->Image->GetHeight(), Gdiplus::UnitPixel);
			left = left + lbi->marginImage + lbi->ImageWidth;
		}
	}

	if ((dis->itemState & ODS_FOCUS) == ODS_FOCUS && GetMember(L"DrawFocusRect") != 0) {  // 焦点
		RECT rc = { 1, 1, dis->rcItem.right - dis->rcItem.left - 1, dis->rcItem.bottom - dis->rcItem.top - 1 };
		DrawFocusRect(hdc, &rc);
	}

	Gdiplus::SolidBrush brush(Color(255, 0, 0, 255));
	if ((dis->itemState & ODS_SELECTED) != 0)
		brush.SetColor(lbi->selTextColor);
	else
		brush.SetColor(lbi->textColor);

	RectF rcf = { (REAL)(left + lbi->marginText), 1.0f, (REAL)(dis->rcItem.right - left + lbi->marginText), (REAL)(dis->rcItem.bottom - dis->rcItem.top) };

	Gdiplus::StringFormat stringFormat(StringFormatFlagsNoWrap);
	stringFormat.SetAlignment(StringAlignmentNear);
	stringFormat.SetLineAlignment(StringAlignmentCenter);

	HFONT hFont = (HFONT)SendMessage(hWnd, WM_GETFONT, 0, 0);
	if (!hFont) return;

	HDC hdc1 = GetDC(hWnd);
	if (!hdc1) return;

	Gdiplus::Font 局部_字体(hdc1, hFont);
	ReleaseDC(hWnd, hdc1);

	if (!lbi->lpString.empty()) {
		Gdiplus::Status lastResult = graphics->DrawString(lbi->lpString.c_str(), -1, &局部_字体, rcf, &stringFormat, &brush);
        if (lastResult != Gdiplus::Ok) {
			return;
		}
	}
}
void DarkMoonUI::zyListBoxEx::zyListBoxEx_OnDrawItem(HWND hWnd, WPARAM wParam , DRAWITEMSTRUCT* dis) {
	zyBuffGraphics* bg = new zyBuffGraphics();
	INT w = dis->rcItem.right - dis->rcItem.left;
	INT h = dis->rcItem.bottom - dis->rcItem.top;
    if(!bg->Create(w, h)) return;
	Gdiplus::Graphics* graphics = bg->GetGraphics();
	//std::wcout << "zyListBoxEx_OnDrawItem  " << graphics  << std::endl;
	zyListBoxEx_DrawBackColor(graphics, dis);
	int left = 0;
	if (GetMember(L"ShowChecked") != 0) {
		left = zyListBoxEx_DrawCheckBox(hWnd, bg->gethdc(), dis);
	}
	zyListBoxEx_DrawImageAndText(hWnd, bg->gethdc(),graphics, dis ,left);
	
	//Gdiplus::Pen p(Color(255,0,0));
	//graphics->DrawRectangle(&p, dis->rcItem.left, dis->rcItem.top, w-1, h);
	bg->Copy2dc(dis->hDC, dis->rcItem.left, dis->rcItem.top, w, h, 0, 0, SRCCOPY);
	delete bg;
}
LRESULT WINAPI DarkMoonUI::zyListBoxEx::zyListBoxEx_ChildWndProc(zyObject* obj, HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, BOOL* bHandle)
{
	if (message == WM_MEASUREITEM)
	{
		zyListBoxEx* zyb = (zyListBoxEx*)obj->getPtrData(L"this");
		zyb->zyListBoxEx_OnMeasureItem(hWnd, lParam);
		*bHandle = true;
		return 1;
	}
	else if (message == WM_DELETEITEM)
	{
		zyListBoxEx* zyb = (zyListBoxEx*)obj->getPtrData(L"this");
		zyb->zyListBoxEx_OnDeleteItem(hWnd, lParam);
		*bHandle = true;
		return 1;
	}
	else if (message == WM_DRAWITEM)
	{
		DRAWITEMSTRUCT *pDrawItemStruct = (DRAWITEMSTRUCT*)lParam;
		if(pDrawItemStruct->CtlType != ODT_LISTBOX)
            return 0;
		zyListBoxEx* zyb = (zyListBoxEx*)obj->getPtrData(L"this");
		zyb->zyListBoxEx_OnDrawItem(pDrawItemStruct->hwndItem, wParam, pDrawItemStruct);
		*bHandle =  true;
		return 1;
	}
	else if (message == WM_COMPAREITEM)
	{
		zyListBoxEx* zyb = (zyListBoxEx*)obj->getPtrData(L"this");
		*bHandle = true;
		return zyb->zyListBoxEx_OnCompareItem(hWnd, lParam);
	}
	else if (message == WM_COMMAND)
	{
		short id = LOWORD(wParam);// & 65535); //LOWORD
		int code = HIWORD(wParam);
		if (code == LBN_SELCHANGE) {
			TRegEvent* evtPtr = (TRegEvent*)obj->getPtrData(L"OnSelChange");
			if (evtPtr != nullptr) {
				evtPtr->handler<LRESULT>(lParam ,id);
			}
		}
		else if (code == LBN_DBLCLK) {
			TRegEvent* evtPtr = (TRegEvent*)obj->getPtrData(L"OnItemDBClick");
			if (evtPtr != nullptr)
				evtPtr->handler<LRESULT>(lParam, id);
		}
		else if (code == LBN_SELCANCEL) {
			TRegEvent* evtPtr = (TRegEvent*)obj->getPtrData(L"OnSelCancel");
			if (evtPtr != nullptr)
				evtPtr->handler<LRESULT>(lParam, id);
		}
	}
	return zyCtrol::zyCtrol_ChildWndProc(obj, hWnd, message, wParam, lParam, bHandle);
}
void DarkMoonUI::zyListBoxEx::zyListBoxEx_OnDeleteItem(HWND hWnd, LPARAM lParam) {
	DELETEITEMSTRUCT* dis = (DELETEITEMSTRUCT*)lParam;
	if(dis->itemData){
		std::vector<zyListBoxItem*>* zyListBoxItems = (std::vector<zyListBoxItem*>*)GetMember(L"zyListBoxItems");
		if (zyListBoxItems != nullptr) {
			zyListBoxItem* lbi = (zyListBoxItem*)dis->itemData;

			if (lbi->NoImageList != 0 && lbi->Image != 0) {
				delete lbi->Image;
			}
			int id = lbi->id;
            zyListBoxItems->erase(zyListBoxItems->begin() + id);
			size_t count = zyListBoxItems->size();
			for (size_t i = 0; i < count; i++) {
				zyListBoxItem* lbi1 = (*zyListBoxItems)[i];
				if (lbi1 != nullptr) {
					if (lbi1->id > id)
					{
						lbi1->id = lbi1->id - 1;
					}
				}
			}
		}
	}
}
LRESULT DarkMoonUI::zyListBoxEx::zyListBoxEx_OnCompareItem(HWND hWnd, LPARAM lParam) {
	COMPAREITEMSTRUCT* cps = (COMPAREITEMSTRUCT*)lParam;
	if (cps) {
		zyListBoxItem lbItem1, lbItem2;
		if (cps->itemData1 != 0 && cps->itemID1 != -1)
			memcpy(&lbItem1, (void*)cps->itemData1, sizeof(lbItem1));
		if (cps->itemData2 != 0)
			memcpy(&lbItem2, (void*)cps->itemData2, sizeof(lbItem2));
		if (cps->itemID1 == -1) {
			if(cps->itemData1)
				return (StrStrI(lbItem2.lpString.c_str(), (LPCWSTR)cps->itemData1) == NULL) ? -1 : 0;
		}
		else
			return lstrcmpi(lbItem1.lpString.c_str(), lbItem2.lpString.c_str());
	}
	return 0;
}
void DarkMoonUI::zyListBoxEx::zyListBoxEx_OnMeasureItem(HWND hWnd, LPARAM lParam) {
	MEASUREITEMSTRUCT* mss = (MEASUREITEMSTRUCT*)lParam;
	if (mss->itemData){
		zyListBoxItem *lbi = (zyListBoxItem*)mss->itemData;
		mss->itemHeight = lbi->height;
	}
}
LRESULT WINAPI DarkMoonUI::zyListBoxEx::zyListBoxEx_WndProc(zyObject* obj, HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL* bHandle)
{
	if (uMsg == WM_NCDESTROY) {
		zyListBoxEx* zyb = (zyListBoxEx*)obj->getPtrData(L"this");
		zyb->OnNCDestroy();
	}
	else if (uMsg == WM_LBUTTONDOWN || uMsg == WM_LBUTTONDBLCLK) {
		zyListBoxEx* zyb = (zyListBoxEx*)obj->getPtrData(L"this");
		zyb->zyListBoxEx_OnLButtonUp(hWnd, LOWORD(lParam), HIWORD(lParam));
	}
	return zyCustomCtrol::zyCustomCtrol_WndProc(obj, hWnd, uMsg, wParam, lParam, bHandle);
}
void DarkMoonUI::zyListBoxEx::zyListBoxEx_OnLButtonUp(HWND hWnd,INT x,INT  y ) {
	int pos = MAKEWPARAM(x,y);
	int index = (int)SendMessage(hWnd, LB_ITEMFROMPOINT, 0, pos);
	if (HIWORD(index) ==0 ) {
		index = LOWORD(index);
		RECT rc = { 0 };
		SendMessage(hWnd, LB_GETITEMRECT, index, (LPARAM)&rc);
		zyListBoxItem * lbi = (zyListBoxItem*)SendMessage(hWnd, LB_GETITEMDATA, index, 0);
		if (!lbi) {
			return;
		}
		RECT checkRect = { rc.left, rc.top, lbi->marginChecked + 14 + lbi->marginChecked, rc.bottom };
		if (PtInRect(&checkRect, POINT{ x, y }) != 0) {
			if ((lbi->state & zyLBS_CHECKED) != 0) {
				lbi->state &= ~zyLBS_CHECKED;
			}else {
                lbi->state |= zyLBS_CHECKED;
			}
			InvalidateRect(hWnd, &rc, false);
		}
	}
}
void DarkMoonUI::zyListBoxEx::OnNCDestroy() {
	std::vector<zyListBoxItem*>* zyListBoxItems = (std::vector<zyListBoxItem*>*)GetMember(L"zyListBoxItems");
	if (zyListBoxItems != nullptr) {
		size_t count = zyListBoxItems->size();
		for (size_t i = 0; i < count; i++) {
			zyListBoxItem* lbi = (*zyListBoxItems)[i];
			if (lbi != nullptr) {
                if (lbi->NoImageList != 0 && lbi->Image != 0) {
					delete lbi->Image;
				}
				delete lbi;
			}
		}
        delete zyListBoxItems;
		SetMember(L"zyListBoxItems", 0);
	}
	resObject* pImageList = (resObject*)GetMember(L"pImageList");
	if (pImageList != nullptr) {
		//IUnknown_Release (pImageList);
		pImageList->release();
		//delete pImageList;
		SetMember(L"pImageList", 0);
	}
}
void WINAPI DarkMoonUI::zyListBoxEx::zyListBoxEx_Destroy(zyObject* obj)
{
	zyListBoxEx* zyb = (zyListBoxEx*)obj->getPtrData(L"this");
	zyb->OnNCDestroy();
	zyCustomCtrol::zyCustomCtrol_Destroy(obj);
}
BOOL DarkMoonUI::zyListBoxEx::创建(HWND 参数_父窗口, const std::wstring& 参数_标题, POINT 参数_位置, POINT 参数_尺寸, int 参数_ID, int 参数_窗口风格, int 参数_扩展风格)
{
	if (GetMember(L"zyListBoxItems") == 0) {
		std::vector<zyListBoxItem*>* zyListBoxItems = new std::vector<zyListBoxItem*>();
		SetMember(L"zyListBoxItems", (LONG_PTR)zyListBoxItems);
	}
	if (HasMember(L"DrawFocusRect") == 0)
		SetMember(L"DrawFocusRect", 1);
	if (HasMember(L"ShowChecked") == 0)
		SetMember(L"ShowChecked", 1);
	if (参数_窗口风格 == 0)
		参数_窗口风格 = LBS_USETABSTOPS | WS_VSCROLL | WS_TABSTOP ;
	if (参数_ID == NULL)
		参数_ID = 黑月默认ID();
	if (参数_扩展风格 == 0)
		参数_扩展风格 = WS_EX_CLIENTEDGE;

	if(zyWindow_SuperClass(L"Listbox", L"zyListBoxEx") == false)
		return false;

	return _CreateCtrol(参数_父窗口, 参数_标题, 参数_位置, 参数_尺寸, 参数_ID, 参数_窗口风格 | LBS_NOTIFY | LBS_NOINTEGRALHEIGHT | LBS_OWNERDRAWVARIABLE,
		参数_扩展风格, L"zyListBoxEx");
}

BOOL DarkMoonUI::zyListBoxEx::创建(zyWindow& 参数_父窗口, const std::wstring& 参数_标题, POINT 参数_位置, POINT 参数_尺寸, int 参数_ID, int 参数_窗口风格, int 参数_扩展风格)
{
	
	if (GetMember(L"zyListBoxItems") == 0) {
		std::vector<zyListBoxItem*>* zyListBoxItems = new std::vector<zyListBoxItem*>();
		SetMember(L"zyListBoxItems", (LONG_PTR)zyListBoxItems);
	}
	if (HasMember(L"DrawFocusRect") == 0)
		SetMember(L"DrawFocusRect", 1);
	if (HasMember(L"ShowChecked") == 0)
		SetMember(L"ShowChecked", 1);
	
	if (参数_窗口风格 == 0)
		参数_窗口风格 = LBS_USETABSTOPS | WS_VSCROLL | WS_TABSTOP | WS_BORDER;
	if (参数_ID == NULL)
		参数_ID = 黑月默认ID();
	if (参数_扩展风格 == 0)
		参数_扩展风格 = WS_EX_CLIENTEDGE;
	if (zyWindow_SuperClass(L"Listbox", L"zyListBoxEx") == false)
		return false;
	return _CreateCtrol(参数_父窗口.getHwnd(), 参数_标题, 参数_位置, 参数_尺寸, 参数_ID, 参数_窗口风格 | LBS_NOTIFY | LBS_NOINTEGRALHEIGHT | LBS_OWNERDRAWVARIABLE, 参数_扩展风格, L"zyListBoxEx");
}
int DarkMoonUI::zyListBoxEx::加入项目(const std::wstring& 参数_项目文本, int 参数_项目数值, int 参数_图片索引, int 参数_项目高度) {

	std::vector<zyListBoxItem*>* zyListBoxItems = (std::vector<zyListBoxItem*>*)GetMember(L"zyListBoxItems");
	if (zyListBoxItems == nullptr)
		return -1;
	// 创建列表框项
	zyListBoxItem* lbi = new zyListBoxItem{ 0 };
	lbi->mask = zyLBM_STRING | zyLBM_IMAGE | zyLBM_HEIGHT | zyLBM_LPARAM;
	lbi->lpString = 参数_项目文本; // 直接使用 std::wstring，无需手动管理内存
	lbi->iImage = 参数_图片索引;
	lbi->height = 参数_项目高度;
	lbi->lParam = 参数_项目数值;
	lbi->textColor = Gdiplus::Color::Black; // 黑色
	lbi->backColor = Gdiplus::Color::White; // 白色
	lbi->selTextColor = Gdiplus::Color::Black; // 黑色
	lbi->selBackColor = Gdiplus::Color(0,120,215); 
	lbi->marginChecked = 2;
	lbi->marginImage = 2;
	lbi->marginText = 2;
	lbi->id = (int)zyListBoxItems->size(); // 使用 std::vector 的 size() 获取当前项的数量

	// 将项添加到 std::vector 中
	zyListBoxItems->push_back(lbi);
	// 获取添加项的索引
	int 局部_索引 = (int)zyListBoxItems->size() - 1;
	if (局部_索引 == -1)
		return 局部_索引;
	// 将 zyListBoxItem 指针设置为列表框项的 itemData
	return (int)sendMsg(LB_ADDSTRING, 0, (LPARAM)(*zyListBoxItems)[局部_索引]);
}
int DarkMoonUI::zyListBoxEx::插入项目(const std::wstring& 参数_项目文本, int 参数_插入位置, int 参数_项目数值, int 参数_图片索引, int 参数_项目高度) {

	std::vector<zyListBoxItem*>* zyListBoxItems = (std::vector<zyListBoxItem*>*)GetMember(L"zyListBoxItems");
	if (zyListBoxItems == nullptr)
		return -1;
	// 创建列表框项
	zyListBoxItem* lbi = new zyListBoxItem{ 0 };
	lbi->mask = zyLBM_STRING | zyLBM_IMAGE | zyLBM_HEIGHT | zyLBM_LPARAM;
	lbi->lpString = 参数_项目文本; // 直接使用 std::wstring，无需手动管理内存
	lbi->iImage = 参数_图片索引;
	lbi->height = 参数_项目高度;
	lbi->lParam = 参数_项目数值;
	lbi->textColor = Gdiplus::Color::Black; // 黑色
	lbi->backColor = Gdiplus::Color::White; // 白色
	lbi->selTextColor = Gdiplus::Color::Black; // 黑色
	lbi->selBackColor = Gdiplus::Color(0, 120, 215);
	lbi->marginChecked = 2;
	lbi->marginImage = 2;
	lbi->marginText = 2;
	lbi->id = (int)zyListBoxItems->size(); // 使用 std::vector 的 size() 获取当前项的数量

	// 将项添加到 std::vector 中
	zyListBoxItems->push_back(lbi);
	// 获取添加项的索引
	int 局部_索引 = (int)zyListBoxItems->size() - 1;
	if(局部_索引 == -1)
        return 局部_索引;
	// 将 zyListBoxItem 指针设置为列表框项的 itemData
	return (int)sendMsg(LB_INSERTSTRING, 参数_插入位置, (LPARAM)(*zyListBoxItems)[局部_索引]);
}
bool DarkMoonUI::zyListBoxEx::删除项目(int 参数_项目索引) {//删除指定项目。成功返回真，失败返回假。
	return sendMsg(LB_DELETESTRING, 参数_项目索引, 0) != LB_ERR;
}
bool DarkMoonUI::zyListBoxEx::清空() {//删除列表框中的所有项目。成功返回真，失败返回假。
	return sendMsg(LB_RESETCONTENT, 0, 0) != LB_ERR;
}
bool DarkMoonUI::zyListBoxEx::显示检查框(bool 参数_显示检查框) {
	int ShowChecked = (int)GetMember(L"ShowChecked");
	SetMember(L"ShowChecked", 参数_显示检查框);
	重画();
	return ShowChecked != 0;
}
void DarkMoonUI::zyListBoxEx::置图片组(zyLmageList& 参数_图片组) {
	resObject* pImageList = reinterpret_cast<resObject*>(GetMember(L"pImageList"));
	if (pImageList != nullptr)
		pImageList->release();
	pImageList = 参数_图片组.getObject();
	pImageList->addRef();
	SetMember(L"pImageList", (LONG_PTR)pImageList);
	重画();
}
DarkMoonUI::zyLmageList DarkMoonUI::zyListBoxEx::取图片组() {
	resObject* pImageList = (resObject*)GetMember(L"pImageList");
	if (pImageList != nullptr) {
		zyLmageList imagelist;
		imagelist.setObject(pImageList);
		return imagelist;
	}
	return zyLmageList();
}
void DarkMoonUI::zyListBoxEx::重画项目(int 参数_索引) {
	RECT rc = {0};
	if (sendMsg(LB_GETITEMRECT, 参数_索引, (LPARAM)&rc) != LB_ERR) {
		InvalidateRect(取窗口句柄(), &rc, false);
	}
}
bool DarkMoonUI::zyListBoxEx::置图片(int 参数_索引, Gdiplus::Image* 参数_图片, int 参数_图片宽度, int 参数_图片高度) {
	zyListBoxItem* lbi = (zyListBoxItem*)sendMsg(LB_GETITEMDATA, 参数_索引, 0);
	if (lbi == nullptr) {
		return false;
	}
	lbi->NoImageList = 1;
	lbi->Image = 参数_图片;
	//IUnknown_AddRef(lbi.Image);
	if (参数_图片宽度==-1) {
		lbi->ImageWidth = 参数_图片->GetWidth();
	}
	else {
		lbi->ImageWidth = 参数_图片宽度;
	}
	if (参数_图片高度==-1) {
		lbi->ImageHeight = 参数_图片->GetHeight();
	}
	else {
		lbi->ImageHeight = 参数_图片高度;
	}

	if (sendMsg(LB_SETITEMDATA, 参数_索引, (LPARAM)lbi) != LB_ERR) {
		重画项目(参数_索引);
		return true;
	}
	return false;
}
Gdiplus::Image* DarkMoonUI::zyListBoxEx::取图片(int 参数_索引) {
	
	zyListBoxItem* lbi = (zyListBoxItem*)sendMsg(LB_GETITEMDATA, 参数_索引, 0);
	if (lbi == nullptr) {
		return nullptr;
	}
	if (lbi->NoImageList == 0 || lbi->Image == 0) {
		return nullptr;
	}
	Gdiplus::Image* img = (Gdiplus::Image*)lbi->Image;
	return img;
}
bool DarkMoonUI::zyListBoxEx::置图片索引(int 参数_索引, int 参数_图片索引) {
	zyListBoxItem* lbi = (zyListBoxItem*)sendMsg(LB_GETITEMDATA, 参数_索引, 0);
	if (lbi == nullptr) {
		return false;
	}
	lbi->NoImageList = 0;
	lbi->iImage = 参数_图片索引;
	if (sendMsg(LB_SETITEMDATA, 参数_索引, (LPARAM)lbi) != LB_ERR) {
		重画项目(参数_索引);
		return true;
	}
	return false;
}
int DarkMoonUI::zyListBoxEx::取图片索引(int 参数_索引) {
	zyListBoxItem* lbi = (zyListBoxItem*)sendMsg(LB_GETITEMDATA, 参数_索引, 0);
	if (lbi == nullptr) {
		return -1;
	}
	if (lbi->NoImageList != 0) {
		return -1;
	}
	return lbi->iImage;
}
std::wstring DarkMoonUI::zyListBoxEx::取项目文本(int 参数_索引) {
	zyListBoxItem* lbi = (zyListBoxItem*)sendMsg(LB_GETITEMDATA, 参数_索引, 0);
	if (lbi == nullptr) {
		return L"";
	}
	if (lbi->lpString.empty()) {
		return L"";
	}
	return lbi->lpString;
}
bool DarkMoonUI::zyListBoxEx::置项目文本(int 参数_索引, const std::wstring& 参数_项目文本) {
	zyListBoxItem* lbi = (zyListBoxItem*)sendMsg(LB_GETITEMDATA, 参数_索引, 0);
	if (lbi == nullptr) {
		return false;
	}
	lbi->lpString = 参数_项目文本;
	if (sendMsg(LB_SETITEMDATA, 参数_索引, (LPARAM)lbi) != LB_ERR) {
		重画项目(参数_索引);
		return true;
	}
	return false;
}
bool DarkMoonUI::zyListBoxEx::取检查框状态(int 参数_索引) {
	zyListBoxItem* pItemData = (zyListBoxItem*)sendMsg(LB_GETITEMDATA, 参数_索引, 0);
	if (pItemData == nullptr) {
		return false;
	}
	return (pItemData->state & zyLBS_CHECKED) != 0;
}
bool DarkMoonUI::zyListBoxEx::置检查框状态(int 参数_索引, bool 参数_检查框状态) {
	zyListBoxItem* pItemData = (zyListBoxItem*)sendMsg(LB_GETITEMDATA, 参数_索引, 0);
	if (pItemData == nullptr) {
		return false;
	}
	if (参数_检查框状态) {
		pItemData->state |= zyLBS_CHECKED;
	}
	else {
		pItemData->state &= (~zyLBS_CHECKED);
	}
	if (sendMsg(LB_SETITEMDATA, 参数_索引, (LPARAM)pItemData) != LB_ERR) {
		重画项目(参数_索引);
		return true;
	}
	return false;
}
bool DarkMoonUI::zyListBoxEx::置项目高度(int 参数_索引, int 参数_高度) {//成功返回真，失败返回假。
	int 返回值 = (int)sendMsg(LB_SETITEMHEIGHT, 参数_索引, 参数_高度);
	if (是否已创建()) {
		重画(false);
	}
	return 返回值 != LB_ERR;
}
int DarkMoonUI::zyListBoxEx::取项目高度(int 参数_索引) {//返回项目高度。
	return (int)sendMsg(LB_GETITEMHEIGHT, 参数_索引, 0);
}
Gdiplus::Color DarkMoonUI::zyListBoxEx::取项目文本色(int 参数_索引) {//ARGB颜色值
	zyListBoxItem* pItemData = (zyListBoxItem*)sendMsg(LB_GETITEMDATA, 参数_索引, 0);
	if (pItemData == nullptr) {
		return 0;
	}
	return pItemData->textColor;
}
Gdiplus::Color DarkMoonUI::zyListBoxEx::置项目文本色(int 参数_索引, Gdiplus::Color 参数_项目文本色) {//ARGB颜色值
	zyListBoxItem* pItemData = (zyListBoxItem*)sendMsg(LB_GETITEMDATA, 参数_索引, 0);
	if (pItemData == nullptr) {
		return 0;
	}
	Gdiplus::Color color = pItemData->textColor;
	pItemData->textColor = 参数_项目文本色;
	if (sendMsg(LB_SETITEMDATA, 参数_索引, (LPARAM)pItemData) != LB_ERR) {
		重画项目(参数_索引);
	}
	return color;
}
Gdiplus::Color DarkMoonUI::zyListBoxEx::取项目背景色(int 参数_索引) {//ARGB颜色值
	zyListBoxItem* pItemData = (zyListBoxItem*)sendMsg(LB_GETITEMDATA, 参数_索引, 0);
	if (pItemData == nullptr) {
		return 0;
	}
	return pItemData->backColor;
}
Gdiplus::Color DarkMoonUI::zyListBoxEx::置项目背景色(int 参数_索引, Gdiplus::Color 参数_项目背景色) {//ARGB颜色值
	zyListBoxItem* pItemData = (zyListBoxItem*)sendMsg(LB_GETITEMDATA, 参数_索引, 0);
	if (pItemData == nullptr) {
		return 0;
	}
	Gdiplus::Color color = pItemData->backColor;
	pItemData->backColor = 参数_项目背景色;
	if (sendMsg(LB_SETITEMDATA, 参数_索引, (LPARAM)pItemData) != LB_ERR) {
		重画项目(参数_索引);
	}
	return color;
}
Gdiplus::Color DarkMoonUI::zyListBoxEx::取选择项目文本色(int 参数_索引) {//ARGB颜色值
	zyListBoxItem* pItemData = (zyListBoxItem*)sendMsg(LB_GETITEMDATA, 参数_索引, 0);
	if (pItemData == nullptr) {
		return 0;
	}
	return pItemData->selTextColor;
}
Gdiplus::Color DarkMoonUI::zyListBoxEx::置选择项目文本色(int 参数_索引, Gdiplus::Color 参数_选择项目文本色) {//ARGB颜色值
	zyListBoxItem* pItemData = (zyListBoxItem*)sendMsg(LB_GETITEMDATA, 参数_索引, 0);
	if (pItemData == nullptr) {
		return 0;
	}
	Gdiplus::Color color = pItemData->selTextColor;
	pItemData->selTextColor = 参数_选择项目文本色;
	if (sendMsg(LB_SETITEMDATA, 参数_索引, (LPARAM)pItemData) != LB_ERR) {
		重画项目(参数_索引);
	}
	return color;
}
Gdiplus::Color DarkMoonUI::zyListBoxEx::取选择项目背景色(int 参数_索引) {//ARGB颜色值
	zyListBoxItem* pItemData = (zyListBoxItem*)sendMsg(LB_GETITEMDATA, 参数_索引, 0);
	if (pItemData == nullptr) {
		return 0;
	}
	return pItemData->selBackColor;
}
Gdiplus::Color DarkMoonUI::zyListBoxEx::置选择项目背景色(int 参数_索引, Gdiplus::Color 参数_选择项目背景色) {//ARGB颜色值
	zyListBoxItem* pItemData = (zyListBoxItem*)sendMsg(LB_GETITEMDATA, 参数_索引, 0);
	if (pItemData == nullptr) {
		return 0;
	}
	Color color = pItemData->selBackColor;
	pItemData->selBackColor = 参数_选择项目背景色;

	if (sendMsg(LB_SETITEMDATA, 参数_索引, (LPARAM)pItemData) != LB_ERR) {
		重画项目(参数_索引);
	}
	return color;
}
LPARAM DarkMoonUI::zyListBoxEx::取项目数值(int 参数_索引) {
	zyListBoxItem* pItemData = (zyListBoxItem*)sendMsg(LB_GETITEMDATA, 参数_索引, 0);
	if (pItemData == nullptr) {
		return 0;
	}
	return pItemData->lParam;
}
LPARAM DarkMoonUI::zyListBoxEx::置项目数值(int 参数_索引, LPARAM 参数_项目数值) {//ARGB颜色值
	zyListBoxItem* pItemData = (zyListBoxItem*)sendMsg(LB_GETITEMDATA, 参数_索引, 0);
	if (pItemData == nullptr) {
		return 0;
	}
	LPARAM lParam = pItemData->lParam;
	pItemData->lParam = 参数_项目数值;
	sendMsg(LB_SETITEMDATA, 参数_索引, (LPARAM)pItemData);
	return lParam;
}
int DarkMoonUI::zyListBoxEx::置图片缩进距离(int 参数_索引, int 参数_缩进距离) {
	zyListBoxItem* pItemData = (zyListBoxItem*)sendMsg(LB_GETITEMDATA, 参数_索引, 0);
	if (pItemData == nullptr) {
		return 0;
	}
	int marginImage = pItemData->marginImage;
	pItemData->marginImage = 参数_缩进距离;
	sendMsg(LB_SETITEMDATA, 参数_索引, (LPARAM)pItemData);
	return marginImage;
}
int DarkMoonUI::zyListBoxEx::取图片缩进距离(int 参数_索引) {
	zyListBoxItem* pItemData = (zyListBoxItem*)sendMsg(LB_GETITEMDATA, 参数_索引, 0);
	if (pItemData == nullptr) {
		return 0;
	}
	return pItemData->marginImage;
}
int DarkMoonUI::zyListBoxEx::置文本缩进距离(int 参数_索引, int 参数_缩进距离) {
	zyListBoxItem* pItemData = (zyListBoxItem*)sendMsg(LB_GETITEMDATA, 参数_索引, 0);
	if (pItemData == nullptr) {
		return 0;
	}
	int marginText = pItemData->marginText;
	pItemData->marginText = 参数_缩进距离;
	sendMsg(LB_SETITEMDATA, 参数_索引, (LPARAM)pItemData);
	return marginText;
}
int DarkMoonUI::zyListBoxEx::取文本缩进距离(int 参数_索引) {
	zyListBoxItem *pItemData = (zyListBoxItem*)sendMsg(LB_GETITEMDATA, 参数_索引, 0);
	if (pItemData == nullptr) {
		return 0;
	}
	return pItemData->marginText;
}
int DarkMoonUI::zyListBoxEx::取现行选中项() {//本方法仅适用于单选择列表框。成功返回现行选中项索引，失败返回-1。
	return (int)sendMsg(LB_GETCURSEL, 0, 0);
}
int DarkMoonUI::zyListBoxEx::置现行选中项(int 参数_项目索引) {//本方法仅适用于单选择列表框。失败返回-1，注意：参数"项目索引"为-1时，将始终返回-1。
	return (int)sendMsg(LB_SETCURSEL, 参数_项目索引, 0);
}
int DarkMoonUI::zyListBoxEx::查找(const std::wstring& 参数_匹配文本, int 参数_起始索引) {//成功返回找到的索引，失败返回-1。忽略大小写，仅支持包含"列表框_自动排序"风格的列表框
	return (int)sendMsg(LB_FINDSTRING, 参数_起始索引, (LPARAM)参数_匹配文本.c_str());
}
int DarkMoonUI::zyListBoxEx::取项目数() {//成功返回项目总数。
	return (int)sendMsg(LB_GETCOUNT, 0, 0);
}
bool DarkMoonUI::zyListBoxEx::是否被选择(int 参数_项目索引) {//如果指定项目被选择，则返回真，否则返回假。
	return (int)sendMsg(LB_GETSEL, 参数_项目索引, 0) != 0;
}
int DarkMoonUI::zyListBoxEx::取已选择项目数() {//本方法仅适用于多选择列表框才能成功，返回已被选择项目的数目。失败返回-1。
	return (int)sendMsg(LB_GETSELCOUNT, 0, 0);
}
int DarkMoonUI::zyListBoxEx::取所有被选择项(std::vector<int>& 参数_索引数组) {//本方法仅适用于多选择列表框才能成功,返回被选择数目。失败返回-1。
	int 数量 = (int)sendMsg(LB_GETSELCOUNT, 0, 0);
	if (数量 <= 0) {
		return 数量;
	}
	参数_索引数组.resize(数量);
	sendMsg(LB_GETSELITEMS, 数量, (LPARAM)参数_索引数组.data());
	return 数量;
}
int DarkMoonUI::zyListBoxEx::取顶端可见项() {//成功返回顶端可见项目的索引，索引从0开始。失败返回-1。
	return (int)sendMsg(LB_GETTOPINDEX, 0, 0);
}
bool DarkMoonUI::zyListBoxEx::置顶端可见项(int 参数_项目索引) {//设置列表框中当前最顶端的可见项目，必要时将自动滚动列表框。成功返回真，失败返回假。
	return (int)sendMsg(LB_SETTOPINDEX, 参数_项目索引, 0) != LB_ERR;
}
int DarkMoonUI::zyListBoxEx::取焦点项目() {//成功返回当前焦点项目的位置索引。如果在单选列表框中使用本命令，将返回当前被选择项目的位置索引。失败返回-1。
	return (int)sendMsg(LB_GETCARETINDEX, 0, 0);
}
bool DarkMoonUI::zyListBoxEx::置焦点项目(int 参数_项目索引) {//本命令仅在多选列表框中使用，用作设置当前焦点项目。如果在单选列表框中使用本命令，将设置当前被选择项目。成功返回真，失败返回假。
	return (int)sendMsg(LB_SETCARETINDEX, 参数_项目索引, 0) != LB_ERR;
}
RECT DarkMoonUI::zyListBoxEx::取项目矩形(int 参数_项目索引) {
	RECT 局部_矩形 = {0};
	sendMsg(LB_GETITEMRECT, 参数_项目索引, (LPARAM)&局部_矩形);
	return 局部_矩形;
}
int DarkMoonUI::zyListBoxEx::取坐标项目(int 参数_横坐标, int 参数_纵坐标) {//取指定坐标的项目索引。返回-1表示所在坐标无项目。
	int 位置 = MAKEWPARAM(参数_横坐标, 参数_纵坐标);
	int 返回值 = (int)sendMsg(LB_ITEMFROMPOINT, 0, 位置);
	return LOWORD(返回值);
}
bool DarkMoonUI::zyListBoxEx::绘制焦点(bool 参数_绘制焦点) {
	int DrawFocusRect = (int)GetMember(L"DrawFocusRect");
	
	SetMember(L"DrawFocusRect", 参数_绘制焦点);
	重画();

	return DrawFocusRect != 0;
}